﻿using System;
using System.Collections.Generic;
using System.Linq;
using StockCrawlerLib.DAL;
using StockCrawlerLib;
using CrawlerCore;
using HtmlAgilityPack;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Web;
using System.Threading.Tasks;
using System.Net;
using System.Text;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace CrawlerController
{

    public class FptsCrawler2 : BaseCrawler
    {
        public byte[] ReadFully(Stream stream)
        {
            var buffer = new byte[32768];
            using (var ms = new MemoryStream())
            {
                while (true)
                {
                    int read = stream.Read(buffer, 0, buffer.Length);
                    if (read <= 0)
                        return ms.ToArray();
                    ms.Write(buffer, 0, read);
                }
            }
        }

        private string SendRequest(string url, System.Net.CookieCollection cookieCollect, string postParams)
        {
            var req = (HttpWebRequest)WebRequest.Create(url);
            req.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
            req.Accept = "application/json, text/javascript, */*; q=0.01";
            req.Method = "POST";
            req.KeepAlive = true;
            req.Timeout = System.Threading.Timeout.Infinite;
            req.ReadWriteTimeout = System.Threading.Timeout.Infinite;
            req.ProtocolVersion = HttpVersion.Version10;
            req.AllowWriteStreamBuffering = false;
            //if (cookieCollect != null && cookieCollect.Count > 0)
            //{
            //    req.CookieContainer.Add(cookieCollect);
            //}

            

            byte[] buffer =
                System.Text.Encoding.GetEncoding("UTF-8").GetBytes(postParams);
            req.ContentLength = buffer.Length;
            Stream reqstr = req.GetRequestStream();
            reqstr.Write(buffer, 0, buffer.Length);
            reqstr.Close();

            byte[] myData;
            Stream responseStream;
            using (var webResponse = req.GetResponse())
            {
                responseStream = webResponse.GetResponseStream();
                myData = ReadFully(responseStream);
            }

            // Do whatever you need with the response
            string responseString = Encoding.ASCII.GetString(myData);
            return responseString;
        }

        private void ImportPriceHistoryByStockExchange(string parFromDToD, int san)
        {
            BrowserSession_General br = new BrowserSession_General();
            string currCode = "";
            string url = "http://priceboard.fpts.com.vn/?s=33&t=aHIST_PRICE";
            try
            {
                HtmlDocument doc = br.Get(url);
                System.Net.CookieCollection cookieCollect = br.Response.Cookies;
                url = "http://priceboard.fpts.com.vn/Data.ashx";
                // Do whatever you need with the response
                string postParams = string.Format("action=hist_stock_price&center={0}&code=0&type=2&date=&{1}&selected_page=1&page_size=400", san, parFromDToD);
                string responseString = SendRequest(url, br.Response.Cookies, postParams);

                if (responseString != "")
                {
                    JObject obj = JObject.Parse(responseString);
                    JArray categoriesBody = (JArray)obj["Body"];
                    foreach (JToken objTokenData in categoriesBody)
                    {
                        JArray stockArray = (JArray)objTokenData["Data"];

                        currCode = "";
                        //Ngày giao dịch
                        string dateString = stockArray[0][1].ToString();
                        DateTime ngay_giao_dich;
                        if (!DateTime.TryParseExact(dateString, "dd/MM/yyyy", null,
                            DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AdjustToUniversal, out ngay_giao_dich))
                        {
                            //Nếu cột ngày tháng không phải chứa "Tổng" thì có thể báo lỗi
                            if (!dateString.Contains("Tổng"))
                            {
                                //Error
                                string msg = string.Format("Error | {0} - ngay_giao_dich", currCode);
                                SystemConfig.SystemLog.Add(msg);
                            }
                            continue;
                        }

                        //Mã
                        currCode = stockArray[1][1].ToString();
                        if (currCode == "BHN")
                            currCode = "BHN";
                        if (currCode == "")
                        {
                            //Error
                            string msg = string.Format("Error | Không thấy mã cổ phiếu", currCode);
                            SystemConfig.SystemLog.Add(msg);
                            continue;
                        }

                        //Khởi tạo object history
                        history objHistory;
                        //UPCOM
                        bool isExist = InitHistory(currCode, san, ngay_giao_dich, out objHistory);
                        
                        //Giá tham chiếu
                        float gia_tham_chieu;
                        if (float.TryParse(stockArray[2][1].ToString(), out gia_tham_chieu))
                        {
                            objHistory.gia_tham_chieu = gia_tham_chieu;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - gia_dong_cua", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Giá trần
                        float gia_tran = -1;
                        if (float.TryParse(stockArray[3][1].ToString(), out gia_tran))
                        {
                            objHistory.gia_tran = gia_tran;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - gia_tran", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Giá sàn
                        float gia_san = -1;
                        if (float.TryParse(stockArray[4][1].ToString(), out gia_san))
                        {
                            objHistory.gia_san = gia_san;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - gia_san", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Giá mở cửa
                        float gia_mo_cua = -1;
                        if (float.TryParse(stockArray[5][1].ToString(), out gia_mo_cua))
                        {
                            objHistory.gia_mo_cua = gia_mo_cua;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - gia_mo_cua", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Giá đóng cửa
                        float gia_dong_cua;
                        if (float.TryParse(stockArray[6][1].ToString(), out gia_dong_cua))
                        {
                            objHistory.gia_dong_cua = gia_dong_cua;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - gia_dong_cua", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Giá cao nhất
                        float gia_cao_nhat = -1;
                        if (float.TryParse(stockArray[7][1].ToString(), out gia_cao_nhat))
                        {
                            objHistory.gia_cao_nhat = gia_cao_nhat;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - gia_cao_nhat", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Giá thấp nhất
                        float gia_thap_nhat = -1;
                        if (float.TryParse(stockArray[8][1].ToString(), out gia_thap_nhat))
                        {
                            objHistory.gia_thap_nhat = gia_thap_nhat;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - gia_thap_nhat", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Thay đổi
                        float thay_doi = -1;
                        if (float.TryParse(stockArray[10][1].ToString(), out thay_doi))
                        {
                            objHistory.thay_doi = thay_doi;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - thay_doi", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Thay đổi %
                        float thay_doi_percent = -1;
                        if (float.TryParse(stockArray[11][1].ToString(), out thay_doi_percent))
                        {
                            objHistory.thay_doi_percent = thay_doi_percent;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - thay_doi_percent", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Khối lượng khớp lệnh
                        int klgd_khop_lenh = -1;
                        if (int.TryParse(stockArray[12][1].ToString(), NumberStyles.Integer | NumberStyles.AllowThousands, null, out klgd_khop_lenh))
                        {
                            objHistory.klgd_khop_lenh = klgd_khop_lenh;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - klgd_khop_lenh", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Khối lượng thỏa thuận
                        int klgd_thoa_thuan = -1;
                        if (int.TryParse(stockArray[13][1].ToString(), NumberStyles.Integer | NumberStyles.AllowThousands, null, out klgd_thoa_thuan))
                        {
                            objHistory.klgd_thoa_thuan = klgd_thoa_thuan;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - klgd_thoa_thuan", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Giá trị khớp lệnh
                        double gtgd_khop_lenh = -1;
                        if (double.TryParse(stockArray[15][1].ToString(), NumberStyles.Float | NumberStyles.AllowThousands, null, out gtgd_khop_lenh))
                        {
                            objHistory.gtgd_khop_lenh = (decimal)gtgd_khop_lenh * 1000000;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - gtgd_khop_lenh", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Giá trị thỏa thuận
                        double gtgd_thoa_thuan = -1;
                        if (double.TryParse(stockArray[16][1].ToString(), NumberStyles.Float | NumberStyles.AllowThousands, null, out gtgd_thoa_thuan))
                        {
                            objHistory.gtgd_thoa_thuan = (decimal)gtgd_thoa_thuan * 1000000;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - gtgd_thoa_thuan", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Cập nhật vào CSDL
                        if (!isExist)
                            _historyRepository.Insert(objHistory);
                        else
                            _historyRepository.Update(objHistory);
                    }
                }
            }
            catch (Exception ex)
            {
                string msg = string.Format("Error | Không truy vấn được link {0}", url);
                SystemConfig.SystemLog.Add(msg);
                throw ex;
            }
        }


        /// <summary>
        /// Tổng hợp lịch sử giao dịch theo link:
        /// http://priceboard.fpts.com.vn/user/stock/lich-su/?a=1&c=4&s=&t=2&d=03/07/2015&b=03/06/2015&e=03/07/2015&p=1
        /// </summary>
        /// <param name="currCode"></param>
        public override void ImportPriceHisotry(string currCode, DateTime dtStart)
        {
            string parFromDToD = "";
            currCode = "";
            string dt = dtStart.Day.ToString() + "/" + dtStart.Month.ToString() + "/" + dtStart.Year.ToString();
            try
            {

                parFromDToD = string.Format("begin_date={0}%2F{1}%2F{2}&end_date={0}%2F{1}%2F{2}", dtStart.Day.ToString(), dtStart.Month.ToString(), dtStart.Year.ToString());
                ImportPriceHistoryByStockExchange(parFromDToD, (int)enumSAN.HOSE);

                ImportPriceHistoryByStockExchange(parFromDToD, (int)enumSAN.HAX);

                ImportPriceHistoryByStockExchange(parFromDToD, (int)enumSAN.UPCOM);
            }
            catch (Exception ex)
            {
                string msg = string.Format("Error | {0} - Không truy vấn được link {1}", currCode, parFromDToD);
                SystemConfig.SystemLog.Add(msg);
                throw ex;
            }

        }

        private void ImportOrderHistoryByStockExchange(string parFromDToD, int san)
        {
            BrowserSession_General br = new BrowserSession_General();
            string currCode = "";
            string url = "http://priceboard.fpts.com.vn/?s=33&t=aHIST_ORDER";
            try
            {
                HtmlDocument doc = br.Get(url);
                System.Net.CookieCollection cookieCollect = br.Response.Cookies;
                url = "http://priceboard.fpts.com.vn/Data.ashx";
                string postParams = string.Format("action=hist_stock_order&center={0}&code=0&type=2&date=&{1}&selected_page=1&page_size=400", san, parFromDToD);
                string responseString = SendRequest(url, br.Response.Cookies, postParams);

                if (responseString != "")
                {
                    JObject obj = JObject.Parse(responseString);
                    JArray categoriesBody = (JArray)obj["Body"];
                    foreach (JToken objTokenData in categoriesBody)
                    {
                        JArray stockArray = (JArray)objTokenData["Data"];

                        //Ngày giao dịch
                        string dateString = stockArray[0][1].ToString();
                        DateTime ngay_giao_dich;
                        if (!DateTime.TryParseExact(dateString, "dd/MM/yyyy", null,
                            DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AdjustToUniversal, out ngay_giao_dich))
                        {
                            string msg = string.Format("Error | {0} - ngay_giao_dich", currCode);
                            SystemConfig.SystemLog.Add(msg);
                            continue;
                        }

                        //Mã
                        currCode = stockArray[1][1].ToString();

                        //Khởi tạo object history
                        history objHistory;
                        bool isExist = InitHistory(currCode, ngay_giao_dich, out objHistory);
                     
                        //Số lệnh mua
                        int so_lenh_mua;
                        if (int.TryParse(stockArray[2][1].ToString(), NumberStyles.Integer | NumberStyles.AllowThousands, null, out so_lenh_mua))
                        {
                            objHistory.so_lenh_mua = so_lenh_mua;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - so_lenh_mua", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Khối lượng đặt mua
                        int kl_dat_mua;
                        if (int.TryParse(stockArray[3][1].ToString(), NumberStyles.Integer | NumberStyles.AllowThousands, null, out kl_dat_mua))
                        {
                            objHistory.kl_dat_mua = kl_dat_mua;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - kl_dat_mua", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Số lệnh bán
                        int so_lenh_ban;
                        if (int.TryParse(stockArray[4][1].ToString(), NumberStyles.Integer | NumberStyles.AllowThousands, null, out so_lenh_ban))
                        {
                            objHistory.so_lenh_ban = so_lenh_ban;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - so_lenh_ban", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Khối lượng đặt bán
                        int kl_dat_ban;
                        if (int.TryParse(stockArray[5][1].ToString(), NumberStyles.Integer | NumberStyles.AllowThousands, null, out kl_dat_ban))
                        {
                            objHistory.kl_dat_ban = kl_dat_ban;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - kl_dat_ban", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Cập nhật vào CSDL
                        if (!isExist)
                            _historyRepository.Insert(objHistory);
                        else
                            _historyRepository.Update(objHistory);
                    }
                }
            }
            catch (Exception ex)
            {
                string msg = string.Format("Error | Không truy vấn được link {0}", url);
                SystemConfig.SystemLog.Add(msg);
                throw ex;
            }
        }
        /// <summary>
        /// Tổng hợp lịch sử khớp lệnh theo link 
        /// http://priceboard.fpts.com.vn/user/stock/lich-su-lenh/?a=1&c=1&s=&t=5&d=03/07/2015&b=03/06/2015&e=03/07/2015&p=1
        /// </summary>
        /// <param name="currCode"></param>
        public override void ImportOrderHisotry(string currCode, DateTime dtStart)
        {
            string parFromDToD = "";
            try
            {
                parFromDToD = string.Format("begin_date={0}%2F{1}%2F{2}&end_date={0}%2F{1}%2F{2}", dtStart.Day.ToString(), dtStart.Month.ToString(), dtStart.Year.ToString());
                ImportOrderHistoryByStockExchange(parFromDToD, (int)enumSAN.HOSE);

                ImportOrderHistoryByStockExchange(parFromDToD, (int)enumSAN.HAX);

                ImportOrderHistoryByStockExchange(parFromDToD, (int)enumSAN.UPCOM);
            }
            catch (Exception ex)
            {
                string msg = string.Format("Error | Không truy vấn được link {0}", parFromDToD);
                SystemConfig.SystemLog.Add(msg);
                throw ex;
            }
        }

        private void ImportForeignHistoryByStockExchange(string parFromDToD, int san)
        {
            BrowserSession_General br = new BrowserSession_General();
            string currCode = "";
            string url = "http://priceboard.fpts.com.vn/?s=33&t=aHIST_FOREIGN_NM";
            try
            {
                HtmlDocument doc = br.Get(url);
                System.Net.CookieCollection cookieCollect = br.Response.Cookies;
                url = "http://priceboard.fpts.com.vn/Data.ashx";
                string postParams = string.Format("action=hist_stock_foreign_nm&center={0}&code=0&type=2&date=&{1}&selected_page=1&page_size=400", san, parFromDToD);
                string responseString = SendRequest(url, br.Response.Cookies, postParams);

                if (responseString != "")
                {
                    JObject obj = JObject.Parse(responseString);
                    JArray categoriesBody = (JArray)obj["Body"];
                    foreach (JToken objTokenData in categoriesBody)
                    {
                        JArray stockArray = (JArray)objTokenData["Data"];

                        //Ngày giao dịch
                        string dateString = stockArray[0][1].ToString();
                        DateTime ngay_giao_dich;
                        if (!DateTime.TryParseExact(dateString, "dd/MM/yyyy", null,
                            DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AdjustToUniversal, out ngay_giao_dich))
                        {
                            string msg = string.Format("Error | {0} - ngay_giao_dich", currCode);
                            SystemConfig.SystemLog.Add(msg);
                            continue;
                        }

                        //Mã
                        currCode = stockArray[1][1].ToString();

                        //Khởi tạo object history
                        history objHistory;
                        bool isExist = InitHistory(currCode, ngay_giao_dich, out objHistory);
                       
                        //Khối lượng sở hữu nước ngoài được phép
                        int klsh_nn;
                        if (int.TryParse(stockArray[2][1].ToString(), NumberStyles.Integer | NumberStyles.AllowThousands, null, out klsh_nn))
                        {
                            objHistory.klsh_nn = klsh_nn;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - klsh_nn", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //% Sở hữu nước ngoài
                        float klsh_nn_percent;
                        if (float.TryParse(stockArray[3][1].ToString(), NumberStyles.Float, null, out klsh_nn_percent))
                        {
                            objHistory.klsh_nn_percent = klsh_nn_percent;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - klsh_nn_percent", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Khối lượng sở hữu nước ngoài còn lại
                        int klsh_nn_con_lai;
                        if (int.TryParse(stockArray[4][1].ToString(), NumberStyles.Integer | NumberStyles.AllowThousands, null, out klsh_nn_con_lai))
                        {
                            objHistory.klsh_nn_con_lai = klsh_nn_con_lai;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - klsh_nn_con_lai", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Khối lượng mua
                        int klgd_nn_mua;
                        if (int.TryParse(stockArray[5][1].ToString(), NumberStyles.Integer | NumberStyles.AllowThousands, null, out klgd_nn_mua))
                        {
                            objHistory.klgd_nn_mua = klgd_nn_mua;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - klgd_nn_mua", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Khối lượng bán
                        int klgd_nn_ban;
                        if (int.TryParse(stockArray[7][1].ToString(), NumberStyles.Integer | NumberStyles.AllowThousands, null, out klgd_nn_ban))
                        {
                            objHistory.klgd_nn_ban = klgd_nn_ban;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - klgd_nn_ban", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Cập nhật vào CSDL
                        if (!isExist)
                            _historyRepository.Insert(objHistory);
                        else
                            _historyRepository.Update(objHistory);
                    }
                }
            }
            catch (Exception ex)
            {
                string msg = string.Format("Error | Không truy vấn được link {0}", url);
                SystemConfig.SystemLog.Add(msg);
                throw ex;
            }
        }

        /// <summary>
        /// http://priceboard.fpts.com.vn/user/stock/ndtnn/?a=1&c=1&s=&t=5&d=03/07/2015&b=03/06/2015&e=03/07/2015&p=1
        /// </summary>
        /// <param name="currCode"></param>
        /// <param name="dtStart"></param>
        public override void ImportForeignHistory(DateTime dtStart)
        {
            string parFromDToD = "";
            try
            {
                parFromDToD = string.Format("begin_date={0}%2F{1}%2F{2}&end_date={0}%2F{1}%2F{2}", dtStart.Day.ToString(), dtStart.Month.ToString(), dtStart.Year.ToString());
                ImportForeignHistoryByStockExchange(parFromDToD, (int)enumSAN.HOSE);

                ImportForeignHistoryByStockExchange(parFromDToD, (int)enumSAN.HAX);

                ImportForeignHistoryByStockExchange(parFromDToD, (int)enumSAN.UPCOM);
            }
            catch (Exception ex)
            {
                string msg = string.Format("Error | Không truy vấn được link {0}", parFromDToD);
                SystemConfig.SystemLog.Add(msg);
                throw ex;
            }
        }

        private void ImportForeign2HistoryByStockExchange(string parFromDToD, int san)
        {
            BrowserSession_General br = new BrowserSession_General();
            string currCode = "";
            string url = "http://priceboard.fpts.com.vn/?s=33&t=aHIST_FOREIGN_PT";
            try
            {
                HtmlDocument doc = br.Get(url);
                System.Net.CookieCollection cookieCollect = br.Response.Cookies;
                url = "http://priceboard.fpts.com.vn/Data.ashx";
                string postParams = string.Format("action=hist_stock_foreign_pt&center={0}&code=0&type=2&date=&{1}&selected_page=1&page_size=400", san, parFromDToD);
                string responseString = SendRequest(url, br.Response.Cookies, postParams);

                if (responseString != "")
                {
                    JObject obj = JObject.Parse(responseString);
                    JArray categoriesBody = (JArray)obj["Body"];
                    foreach (JToken objTokenData in categoriesBody)
                    {
                        JArray stockArray = (JArray)objTokenData["Data"];

                        //Ngày giao dịch
                        string dateString = stockArray[0][1].ToString();
                        DateTime ngay_giao_dich;
                        if (!DateTime.TryParseExact(dateString, "dd/MM/yyyy", null,
                            DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AdjustToUniversal, out ngay_giao_dich))
                        {
                            string msg = string.Format("Error | {0} - ngay_giao_dich", currCode);
                            SystemConfig.SystemLog.Add(msg);
                            continue;
                        }

                        //Mã
                        currCode = stockArray[1][1].ToString();

                        //Khởi tạo object history
                        history objHistory;
                        bool isExist = InitHistory(currCode, ngay_giao_dich, out objHistory);
                       
                        //Khối lượng giao dịch nước ngoài mua thỏa thuận
                        int klgd_nn_thoa_thuan_mua;
                        if (int.TryParse(stockArray[5][1].ToString(), NumberStyles.Integer | NumberStyles.AllowThousands, null, out klgd_nn_thoa_thuan_mua))
                        {
                            objHistory.klgd_nn_thoa_thuan_mua = klgd_nn_thoa_thuan_mua;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - klgd_nn_thoa_thuan_mua", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //% Giao dịch toàn thị trường

                        //Khối lượng giao dịch nước ngoài bán thỏa thuận
                        int klgd_nn_thoa_thuan_ban;
                        if (int.TryParse(stockArray[7][1].ToString(), NumberStyles.Integer | NumberStyles.AllowThousands, null, out klgd_nn_thoa_thuan_ban))
                        {
                            objHistory.klgd_nn_thoa_thuan_ban = klgd_nn_thoa_thuan_ban;
                        }
                        else
                        {
                            //Error
                            string msg = string.Format("Error | {0} - klgd_nn_thoa_thuan_ban", currCode);
                            SystemConfig.SystemLog.Add(msg);
                        }

                        //Cập nhật vào CSDL
                        if (!isExist)
                            _historyRepository.Insert(objHistory);
                        else
                            _historyRepository.Update(objHistory);

                    }
                }
            }
            catch (Exception ex)
            {
                string msg = string.Format("Error | Không truy vấn được link {0}", url);
                SystemConfig.SystemLog.Add(msg);
                throw ex;
            }
        }

        public override void ImportForeign2History(DateTime dtStart)
        {
            string parFromDToD = "";
            try
            {
                parFromDToD = string.Format("begin_date={0}%2F{1}%2F{2}&end_date={0}%2F{1}%2F{2}", dtStart.Day.ToString(), dtStart.Month.ToString(), dtStart.Year.ToString());
                ImportForeign2HistoryByStockExchange(parFromDToD, (int)enumSAN.HOSE);

                ImportForeign2HistoryByStockExchange(parFromDToD, (int)enumSAN.HAX);

                ImportForeign2HistoryByStockExchange(parFromDToD, (int)enumSAN.UPCOM);
            }
            catch (Exception ex)
            {
                string msg = string.Format("Error | Không truy vấn được link {0}", parFromDToD);
                SystemConfig.SystemLog.Add(msg);
                throw ex;
            }
        }

        public override string GetCurrentInfo(string currCode)
        {
            //http://ezsearch.fpts.com.vn/Services/EzData/Default2.aspx?s=1058
            BrowserSession_General br = new BrowserSession_General();

            string url = string.Format("http://ezsearch.fpts.com.vn/Services/EzData/Default2.aspx?s={0}", currCode);
            HtmlDocument doc = br.Get(url);
            System.Net.CookieCollection cookieCollect = br.Response.Cookies;

            url = string.Format(@"http://ezsearch.fpts.com.vn/Services/EzData/ProcessLoadRuntime.aspx?s={0}&cGroup=Overview&cPath=Services/EzData/Overview", currCode);
            br.SaveCookiesFrom(cookieCollect);
            doc = br.Post(url);

            string content = "";
            if (br.Response != null)
            {
                //string xpath = "//*[@id='tblStockInfo']";
                string xpath = "//*[@id='Table7']";
                HtmlNodeCollection nodeCollection = doc.DocumentNode.SelectNodes(xpath);

                //Kiểm tra có dữ liệu không
                if (nodeCollection == null)
                {
                    string msg = string.Format("Error | {0} - Không truy vấn được link {1}", currCode, url);
                    SystemConfig.SystemLog.Add(msg);
                    return null;
                }
                foreach (HtmlNode node in nodeCollection)
                {
                    content = node.InnerHtml;
                }
            }

            return content;
        }

        /// <summary>
        /// Tổng hợp lịch sử khớp lệnh theo lô trong ngày
        /// http://s.cafef.vn/Lich-su-giao-dich-PVT-6.chn?date=17/06/2015
        /// </summary>
        /// <param name="currCode"></param>
        public void CapNhatGiaThamChieu(string currCode, DateTime ngay_giao_dich)
        {
            //http://s.cafef.vn/Lich-su-giao-dich-L14-2.chn
            BrowserSession_General br = new BrowserSession_General();

            string url = string.Format("http://s.cafef.vn/Lich-su-giao-dich-{0}-6.chn?date={1}", currCode, ngay_giao_dich.ToString("dd/MM/yyyy"));
            HtmlDocument doc = br.Get(url);
            if (br.Response != null)
            {
                string xpath = "//*[@id='price-box']//span[2]";
                HtmlNodeCollection nodeCollection = doc.DocumentNode.SelectNodes(xpath);

                //Kiểm tra có dữ liệu không
                if (nodeCollection == null)
                {
                    string msg = string.Format("Error | {0} - Không truy vấn được link {1}", currCode, url);
                    SystemConfig.SystemLog.Add(msg);
                    return;
                }

                foreach (HtmlNode node in nodeCollection)
                {
                    //Khởi tọa object
                    history objHistory;
                    bool isExist = InitHistory(currCode, ngay_giao_dich, out objHistory);
                
                    float gia_tham_chieu;
                    if (float.TryParse(node.InnerText.Trim(), out gia_tham_chieu))
                    {
                        objHistory.gia_tham_chieu = gia_tham_chieu;
                    }
                    else
                    {
                        //Error
                        string msg = string.Format("Error | {0} - gia_tham_chieu", currCode);
                        SystemConfig.SystemLog.Add(msg);
                    }

                    _historyRepository.Update(objHistory);
                }
            }
        }

        public override void UpdateFPT_IDInfo()
        {
            BrowserSession_General br = new BrowserSession_General();
            int id = -1;
            string code = "";
            string name = "";
            try
            {
                using (var client = new System.Net.WebClient())
                {
                    string result = client.DownloadString("http://ezsearch.fpts.com.vn/Services/EzData/jquery/localdata.js");

                    Regex r = new Regex(@"{i:(?<id>[0-9]+),code:\""(?<code>[A-Z]+)\"",name:\""(?<name>.+)\""}");
                    MatchCollection mc = r.Matches(result);
                    foreach (Match m in mc)
                    {
                        id = int.Parse(m.Groups["id"].Value);
                        code = m.Groups["code"].Value;
                        name = m.Groups["name"].Value;
                        if (_stockRepository.IsExists(code))
                        {
                            stock obj = _stockRepository.Select(code);
                            obj.id_fpt = id;
                            obj.name = name;
                            if (obj != null)
                                _stockRepository.Update(obj);
                        }
                    }

                    //Lấy ds stock có id_fpt
                    List<stock> stockList = _stockRepository.GetStockList().ToList<stock>();
                    RunParallel(stockList, 0, 50);

                }
            }
            catch (Exception ex)
            {
                SystemConfig.SystemLog.Add(ex.Message);
            }
        }


        public override void UpdateEPSInfo()
        {
            //Lấy ds stock có id_fpt
            List<stock> stockList = _stockRepository.GetStockList().ToList<stock>();
            RunParallel(stockList, 0, 50);
        }

        /// <summary>
        ///  http://ezsearch.fpts.com.vn/Services/EzData/ProcessLoadRuntime.aspx?s={0}&cGroup=Overview&cPath=Services/EzData/Overview
        /// </summary>
        /// <param name="stockList"></param>
        /// <param name="startIndex"></param>
        /// <param name="size"></param>
        public void RunParallel(List<stock> stockList, int startIndex, int size)
        {
            //Run parallel
            Parallel.For(0, size, i =>
            //for(int i = 0; i< size; i++)
            {
                BrowserSession_General br = new BrowserSession_General();
                string url = "";
                HtmlDocument doc = null;
                CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");

                StockRepository _stockRepos = new StockRepository();
                stock obj = stockList[i + startIndex];
                if (obj.id_fpt != null)
                {
                    //Lấy kết quả kinh doanh
                    //string url = string.Format(@"http://ezsearch.fpts.com.vn/Services/EzData/ProcessLoadRuntime.aspx?s={0}&cGroup=Finance&cPath=Services/EzData/FinanceReport&ReportID=Rat", obj.id_fpt);
                    //HtmlDocument doc = br.Get(url, true);

                    //Lấy eps, pe
                    url = string.Format(@"http://ezsearch.fpts.com.vn/Services/EzData/ProcessLoadRuntime.aspx?s={0}&cGroup=Overview&cPath=Services/EzData/Overview", obj.id_fpt);
                    br.Referer = string.Format(@"http://ezsearch.fpts.com.vn/Services/EzData/Default2.aspx?s={0}", obj.id_fpt);
                    doc = br.Get(url);

                    if (br.Response != null)
                    {
                        string xpath = "//table[@id='tblOverviewSummary']";
                        //string xpath = "//*[@id='_ctl0_TopInfo11_lblKLDNYHT']";
                        HtmlNodeCollection tableCollection = doc.DocumentNode.SelectNodes(xpath);
                        //Kiểm tra có dữ liệu không
                        if (tableCollection != null)
                        {
                            HtmlNode node = tableCollection[0];
                            obj = _stockRepos.Select(obj.code);
                            Double number = -1;
                            if (Double.TryParse(node.SelectNodes("//span[@id='_ctl0_TopInfo11_lblKLDNYHT']")[0].InnerText, NumberStyles.Number, culture, out number))
                                obj.klcp_niemyet = (int)number;

                            if (Double.TryParse(node.SelectNodes("//span[@id='_ctl0_TopInfo11_lblKLDLHHT']")[0].InnerText, NumberStyles.Number, culture, out number))
                                obj.klcp_luuhanh = (int)number;

                            if (Double.TryParse(node.SelectNodes("//span[@id='_ctl0_TopInfo11_lblEPSbasicFPTS']")[0].InnerText, NumberStyles.Number, culture, out number))
                                obj.eps = (int)number;

                            if (Double.TryParse(node.SelectNodes("//span[@id='_ctl0_TopInfo11_lblPEadjusted4QFPTS']")[0].InnerText, NumberStyles.Number, culture, out number))
                                obj.pe = number;

                            _stockRepos.Update(obj);
                        }
                    }
                }
            });

            //init paramaters after run parallel
            startIndex += size;
            if (startIndex + size > stockList.Count)
            {
                size = stockList.Count - startIndex;
                if (size > 0)
                    RunParallel(stockList, startIndex, size);
            }
            else
            {
                RunParallel(stockList, startIndex, size);
            }
        }

    }
}

